#include <SDL/SDL.h>
#include "gameengine.h"
#include "gamestate.h"
#define TARGET_FPS 30

void CGameEngine::Init(const char* title, int width, int height,
                       int bpp, bool fullscreen)
{
    int flags = SDL_RESIZABLE|SDL_DOUBLEBUF;
    SDL_WM_SetCaption("test", NULL/*const char *icon*/);
    SDL_Init(SDL_INIT_EVERYTHING);

    if ( fullscreen )
    {
        flags = SDL_FULLSCREEN;
    }

    screen = SDL_SetVideoMode(width, height, bpp, flags);

    m_fullscreen = fullscreen;
    m_running = true;

    curTicks = SDL_GetTicks();
}

void CGameEngine::UpdateScreen(void)
{
    SDL_Flip(screen);
}

void CGameEngine::RegulateFPS()
{
    //SDL_Color fgColor={0,0,0}, bgColor = {128, 128, 128};
    //char fps[40];
    Uint32 elapsedTicks = SDL_GetTicks() - curTicks;

    if (1000 / (elapsedTicks+1) > TARGET_FPS)
    {
        SDL_Delay(1000 / TARGET_FPS - elapsedTicks);
    }
    elapsedTicks = SDL_GetTicks() - curTicks;
    curTicks += elapsedTicks;
    //sprintf(fps, "%3d ms, %6.1f fps", elapsedTicks, 1000.0 / (float)elapsedTicks);
    //SDL_Surface *fpsMsg = TTF_RenderText_Shaded(font, fps, fgColor, bgColor);
    //SDL_Rect pos = {10, 240, 0, 0};
    //SDL_BlitSurface(fpsMsg, NULL, screen, &pos);
    //SDL_FreeSurface(fpsMsg);
}

void CGameEngine::Cleanup()
{
    while ( !states.empty() )
    {
        states.back()->Cleanup();
        states.pop_back();
    }

    // switch back to windowed mode so other
    // programs won't get accidentally resized
    if ( m_fullscreen )
    {
        screen = SDL_SetVideoMode(640, 480, 0, 0);
    }

    SDL_Quit();
}

void CGameEngine::ChangeState(CGameState* state)
{
    // cleanup the current state
    if ( !states.empty() )
    {
        states.back()->Cleanup();
        states.pop_back();
    }

    // store and init the new state
    states.push_back(state);
    states.back()->Init();
}

void CGameEngine::PushState(CGameState* state)
{
    // pause current state
    if ( !states.empty() )
    {
        states.back()->Pause();
    }

    // store and init the new state
    states.push_back(state);
    states.back()->Init();
}

void CGameEngine::PopState()
{
    // cleanup the current state
    if ( !states.empty() )
    {
        states.back()->Cleanup();
        states.pop_back();
    }

    // resume previous state
    if ( !states.empty() )
    {
        states.back()->Resume();
    }
}

void CGameEngine::HandleEvents()
{
    // let the state handle events
    states.back()->HandleEvents(this);
}

void CGameEngine::Update()
{
    // let the state update the game
    states.back()->Update(this);
}

void CGameEngine::Draw()
{
    // let the state draw the screen
    states.back()->Draw(this);
}
